package com.difsonapps.android.marker.fragments;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.android.volley.Cache;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.Cache.Entry;
import com.android.volley.Request.Method;
import com.android.volley.toolbox.JsonObjectRequest;
import com.difsonapps.android.marker.AppConstant;
import com.difsonapps.android.marker.CustomRequest;
import com.difsonapps.android.marker.R;
import com.difsonapps.android.marker.R.layout;
import com.difsonapps.android.marker.adapters.FeedListAdapter;
import com.difsonapps.android.marker.adapters.FriendDemandListAdapter;
import com.difsonapps.android.marker.adapters.FriendListAdapter;
import com.difsonapps.android.marker.app.AppController;
import com.difsonapps.android.marker.beans.FeedItem;
import com.difsonapps.android.marker.beans.Friend;
import com.difsonapps.android.marker.beans.User;
import com.difsonapps.android.marker.fragments.HomeFragment.EndlessScrollListener;
import com.difsonapps.android.marker.util.MarkerUtil;

import android.app.Fragment;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.Toast;
import android.widget.AbsListView.OnScrollListener;

public class FriendFragment extends Fragment {
	public static final String ARG_PARAM_CONCERNED_USER = "concerned_user";
    private static final String TAG = FriendFragment.class.getSimpleName();
    private ListView listView;
    private ListView demandsListView;
    private FriendListAdapter listAdapter;
    private FriendDemandListAdapter demandListAdapter;
    private List<Friend> feedItems;
    private List<Friend> demandsItems;
    String nowTxt = null;
	
	User userFrom;
	
	View friends_menu;
	View frienddemands_menu;
	View friendsView;
	View demandsView;
	
	EndlessScrollListener friendsScrollListner = new EndlessScrollListener(5, 0);
	EndlessScrollListener friendDemandsScrollListner = new EndlessScrollListener(5, 1);
	
	public FriendFragment(){}
	
	public static FriendFragment newInstance(User user) {
		FriendFragment fragment = new FriendFragment();
		Bundle args = new Bundle();
		args.putParcelable(ARG_PARAM_CONCERNED_USER, user);
		fragment.setArguments(args);
		return fragment;
	}
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (getArguments() != null) {
			userFrom = getArguments().getParcelable(ARG_PARAM_CONCERNED_USER);
		}
	}
	
	@Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
 
        View rootView = inflater.inflate(R.layout.fragment_friend, container, false);
        
        listView = (ListView) rootView.findViewById(R.id.list);
        demandsListView = (ListView) rootView.findViewById(R.id.listDemands);
        friends_menu = rootView.findViewById(R.id.friends_menu);
        frienddemands_menu = rootView.findViewById(R.id.frienddemands_menu);
        friendsView = rootView.findViewById(R.id.friendsView);
        demandsView = rootView.findViewById(R.id.demandsView);
        
        friends_menu.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				showFriends();
			}
		});
        frienddemands_menu.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				showDemands();
			}
		});
 
        feedItems = new ArrayList<Friend>();
 
        listAdapter = new FriendListAdapter(this.getActivity(), feedItems, this);
        listView.setAdapter(listAdapter);
        
        listView.setOnScrollListener(friendsScrollListner);
 
        demandsItems = new ArrayList<Friend>();
 
        demandListAdapter = new FriendDemandListAdapter(this.getActivity(), demandsItems, this);
        demandsListView.setAdapter(demandListAdapter);
        
        demandsListView.setOnScrollListener(friendDemandsScrollListner);
         
        
        load();
        loadDemands();
         
        return rootView;
    }
	
	private void showFriends(){
		friendsView.setVisibility(View.VISIBLE);
		demandsView.setVisibility(View.GONE);
		friends_menu.setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_layout_menu_item_selected));
		frienddemands_menu.setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_layout_menu_item));
	}
	
	private void showDemands(){
		friendsView.setVisibility(View.GONE);
		demandsView.setVisibility(View.VISIBLE);
		friends_menu.setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_layout_menu_item));
		frienddemands_menu.setBackgroundDrawable(getResources().getDrawable(R.drawable.bg_layout_menu_item_selected));
	}
	
	public void reload(){
    	feedItems.clear();
    	load();
    }
    
    private void load(){
    	// We first check for cached request
    	if(!friendsScrollListner.isCanContinue()) return;
    	Map<String, String> params = new HashMap<String, String>();
        params.put("id", ""+(userFrom==null?0:userFrom.getId()));
        params.put("offset", ""+friendsScrollListner.getOffset());
        params.put("limit", ""+friendsScrollListner.getLimit());
        String url = MarkerUtil.buildUrl(AppConstant.friendsUrl, params);
    	toast(url);
        Cache cache = AppController.getInstance().getRequestQueue().getCache();
        Entry entry = cache.get(url);
        if (entry != null) {
            // fetch the data from cache
            try {
                String data = new String(entry.data, "UTF-8");
                try {
                    parseJsonFeed(new JSONObject(data));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
 
        } else {
            // making fresh volley request and getting json
            JsonObjectRequest jsonReq = new JsonObjectRequest(Method.GET,
            		url, null, new Response.Listener<JSONObject>() {
 
                        @Override
                        public void onResponse(JSONObject response) {
                            VolleyLog.d(TAG, "Response: " + response.toString());
                            if (response != null) {
                                parseJsonFeed(response);
                            }
                        }
                    }, new Response.ErrorListener() {
 
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            VolleyLog.d(TAG, "Error: " + error.getMessage());
                        }
                    });
 
            // Adding request to volley request queue
            AppController.getInstance().addToRequestQueue(jsonReq);
            friendsScrollListner.setLoading2(true);
        }/**/
    }
 
    /**
     * Parsing json reponse and passing the data to feed view list adapter
     * */
    private void parseJsonFeed(JSONObject response) {
        try {
        	//toast(response.toString());
        	if(nowTxt==null && response.has("now")){
        		nowTxt = response.getString("now");
        	}
            JSONArray feedArray = response.getJSONArray("friends");
            if(feedArray.length()==0) friendsScrollListner.setCanContinue(false);
            for (int i = 0; i < feedArray.length(); i++) {
                JSONObject feedObj = (JSONObject) feedArray.get(i);
                Friend item = Friend.parseFromJsonObject(feedObj);
                //item.setNow(nowTxt);
                //item.setRelativeDate(MarkerUtil.getRelativeTime(item.getDate(), item.getNow(), getActivity()));
                friendsScrollListner.setOffset(friendsScrollListner.getOffset()+1);
                if(item==null) continue;
                feedItems.add(item);
            }
 
            // notify data changes to list adapater
            listAdapter.notifyDataSetChanged();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        friendsScrollListner.setLoading2(false);
    }
    

    
    private void loadDemands(){
    	// We first check for cached request
    	if(!friendDemandsScrollListner.isCanContinue()) return;
    	Map<String, String> params = new HashMap<String, String>();
        params.put("id", ""+(userFrom==null?0:userFrom.getId()));
        params.put("offset", ""+friendDemandsScrollListner.getOffset());
        params.put("limit", ""+friendDemandsScrollListner.getLimit());
        String url = MarkerUtil.buildUrl(AppConstant.friendDemandsUrl, params);
    	toast(url);
        Cache cache = AppController.getInstance().getRequestQueue().getCache();
        Entry entry = cache.get(url);
        if (entry != null) {
            // fetch the data from cache
            try {
                String data = new String(entry.data, "UTF-8");
                try {
                    parseJsonDemands(new JSONObject(data));
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
 
        } else {
            // making fresh volley request and getting json
            JsonObjectRequest jsonReq = new JsonObjectRequest(Method.GET,
            		url, null, new Response.Listener<JSONObject>() {
 
                        @Override
                        public void onResponse(JSONObject response) {
                            VolleyLog.d(TAG, "Response: " + response.toString());
                            if (response != null) {
                            	parseJsonDemands(response);
                            }
                        }
                    }, new Response.ErrorListener() {
 
                        @Override
                        public void onErrorResponse(VolleyError error) {
                            VolleyLog.d(TAG, "Error: " + error.getMessage());
                        }
                    });
 
            // Adding request to volley request queue
            AppController.getInstance().addToRequestQueue(jsonReq);
            friendDemandsScrollListner.setLoading2(true);
        }/**/
    }
 
    /**
     * Parsing json reponse and passing the data to feed view list adapter
     * */
    private void parseJsonDemands(JSONObject response) {
        try {
        	//toast(response.toString());
        	if(nowTxt==null && response.has("now")){
        		nowTxt = response.getString("now");
        	}
            JSONArray feedArray = response.getJSONArray("friends");
            if(feedArray.length()==0) friendDemandsScrollListner.setCanContinue(false);
            for (int i = 0; i < feedArray.length(); i++) {
                JSONObject feedObj = (JSONObject) feedArray.get(i);
                Friend item = Friend.parseFromJsonObject(feedObj);
                //item.setNow(nowTxt);
                //item.setRelativeDate(MarkerUtil.getRelativeTime(item.getDate(), item.getNow(), getActivity()));
                friendDemandsScrollListner.setOffset(friendDemandsScrollListner.getOffset()+1);
                if(item==null) continue;
                demandsItems.add(item);
            }
 
            // notify data changes to list adapater
            demandListAdapter.notifyDataSetChanged();
        } catch (JSONException e) {
            e.printStackTrace();
        }
        friendDemandsScrollListner.setLoading2(false);
    }
    
    class EndlessScrollListener implements OnScrollListener {
        private int visibleThreshold = 5;
        private int currentPage = 0;
        private int previousTotal = 0;
        private boolean loading = true;

        
    	private int offset = 0;
    	private int limit = 5;
    	private boolean canContinue = true;
    	private boolean loading2 = false;
    	
    	int mode = 0;//0 pour friend, 1 pour demand

        public int getOffset() {
			return offset;
		}
		public void setOffset(int offset) {
			this.offset = offset;
		}
		public int getLimit() {
			return limit;
		}
		public void setLimit(int limit) {
			this.limit = limit;
		}
		public boolean isCanContinue() {
			return canContinue;
		}
		public void setCanContinue(boolean canContinue) {
			this.canContinue = canContinue;
		}
		public boolean isLoading2() {
			return loading2;
		}
		public void setLoading2(boolean loading2) {
			this.loading2 = loading2;
		}
		public EndlessScrollListener() {
        }
        public EndlessScrollListener(int visibleThreshold, int mode) {
            this.visibleThreshold = visibleThreshold;
            this.mode = mode;
        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {
            if (loading) {
                if (totalItemCount > previousTotal) {
                    loading = false;
                    previousTotal = totalItemCount;
                    currentPage++;
                }
            }
            if ((!loading) &&(!loading2) && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) {
                // I load the next page of gigs using a background task,
                // but you can call any function here.
            	if(mode==0) load();
            	else if(mode==1) loadDemands();
                /*new LoadGigsTask().execute(currentPage + 1);
                loading = true;*/
            }
        }

        @Override
        public void onScrollStateChanged(AbsListView view, int scrollState) {
        }
    }

    
    public void loadAcceptDemand(Friend friend2){
		if(friend2==null) return;
    	Map<String, String> params = new HashMap<String, String>();
        params.put("id", ""+friend2.getId());
        String url = MarkerUtil.buildUrl(AppConstant.acceptDemandUrl, params);
        CustomRequest jsObjRequest = new CustomRequest(
				Method.GET, 
				url, 
				null,
				new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                    	parseJsonActionDemand(response);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                    	//hideProgress();
                    	toast("Error: " + error.getMessage());
                    }
                }
        );
       AppController.getInstance().addToRequestQueue(jsObjRequest);
	}
    public void loadDeclineDemand(Friend friend2){
		if(friend2==null) return;
    	Map<String, String> params = new HashMap<String, String>();
        params.put("id", ""+friend2.getId());
        String url = MarkerUtil.buildUrl(AppConstant.declineDemandUrl, params);
        CustomRequest jsObjRequest = new CustomRequest(
				Method.GET, 
				url, 
				null,
				new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                    	parseJsonActionDemand(response);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                    	//hideProgress();
                    	toast("Error: " + error.getMessage());
                    }
                }
        );
       AppController.getInstance().addToRequestQueue(jsObjRequest);
	}
	
	private void parseJsonActionDemand(JSONObject response) {
        try {
        	toast(response.toString());
        	Friend friend1 = null;
        	Friend friend2 = null;
        	
            if(response.has("success")){
            	if(response.has("friend1")) friend1 = Friend.parseFromJsonObject(response.getJSONObject("friend1"));
            	else friend1 = null;
            	if(response.has("friend2")) friend2 = Friend.parseFromJsonObject(response.getJSONObject("friend2"));
            	else friend2 = null;
            	
            	if(friend1!=null){//ADD Friend 1 add the top of friends list
            		feedItems.add(0, friend1);
            		listAdapter.notifyDataSetChanged();
            	}
            	if(friend2!=null){//Remove friend 2 in the demand list
            		demandsItems.remove(friend2);
            		demandListAdapter.notifyDataSetChanged();
            	}
            	
            }else if(response.has("error")){
            	String error = response.getString("error");
            	//TODO Show the error message in a textView and make it visible
            	toast(error);
            	//hideProgress();
            }
        } catch (JSONException e) {
            e.printStackTrace();
            Log.e("Profile fragment", e.getMessage());
        }
    }
    

	public void loadDeleteFriend(final Friend friend){
		if(friend==null) return;
    	Map<String, String> params = new HashMap<String, String>();
        params.put("id", ""+friend.getId());
        String url = MarkerUtil.buildUrl(AppConstant.deleteFriendUrl, params);
        toast("Delete url : "+url);
        CustomRequest jsObjRequest = new CustomRequest(
				Method.GET, 
				url, 
				null,
				new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                    	parseJsonDeleteFriend(response, friend);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                    	//hideProgress();
                    	toast("Error: " + error.getMessage());
                    }
                }
        );
       AppController.getInstance().addToRequestQueue(jsObjRequest);
	}

	private void parseJsonDeleteFriend(JSONObject response, Friend friend) {
        try {
        	
            if(response.has("success")){
            	
            	if(friend!=null){//ADD Friend 1 add the top of friends list
            		feedItems.remove(friend);
            		listAdapter.notifyDataSetChanged();
            	}
            	
            }else if(response.has("error")){
            	String error = response.getString("error");
            	//TODO Show the error message in a textView and make it visible
            	toast(error);
            	//hideProgress();
            }
        } catch (JSONException e) {
            e.printStackTrace();
            Log.e("Profile fragment", e.getMessage());
        }
    }
    
    private void toast(String text){
		Toast.makeText(this.getActivity(), text, Toast.LENGTH_SHORT).show();
	}
}
